﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace SwimmingCompetitions
{
    public partial class FormMain : Form
    {
        private RaceControl _raceControl;

        private CompetitionModel _competition;

        private readonly List<RaceView> _raceViews = new List<RaceView>();
        
        public FormMain()
        {
            InitializeComponent();
            _competition = new CompetitionModel();
            CompetitionMode.Current = new StartCompetitionMode();
            addRaceControl();
        }

        private void toolStripButtonNewClick(object sender, EventArgs e)
        {
            //todo
        }

        private void resetCompetition()
        {
            while (_raceViews.Count > 0)
            {
                removeRaceView(_raceViews[0]);
            }
            _competition = new CompetitionModel();
        }

        private void addRaceControl()
        {
            _raceControl = new RaceControl();
            _raceControl.AddRace += addRace;
            _flowContainer.Controls.Add(_raceControl);
        }

        private void removeRaceControl()
        {
            _raceControl.AddRace -= addRace;
            _flowContainer.Controls.Remove(_raceControl);
            _raceControl = null;
        }

        private void addRaceView(RaceView view)
        {
            view.Removed += gridRemoved;
            if (!_raceViews.Contains(view))
            {
                _raceViews.Add(view);
            }
            _flowContainer.Controls.Add(view);
        }

        private void addRace(int distance, SwimmingGlobals.Mode mode, SwimmingGlobals.Participants participants)
        {
            var model = _competition.AddRace(distance, mode, participants);
            var view = new RaceView(_competition, model);
            addRaceView(view);
        }

        private void removeRaceView(RaceView view)
        {
            _flowContainer.Controls.Remove(view);
            _raceViews.Remove(view);
        }

        private void gridRemoved(RaceView grid)
        {
            grid.Removed -= gridRemoved;
            removeRaceView(grid);
        }

        private void flowContainerControlAdded(object sender, ControlEventArgs e)
        {
            _flowContainer.ControlAdded -= flowContainerControlAdded;
            removeRaceControl();
            addRaceControl();
            _flowContainer.ControlAdded += flowContainerControlAdded;
        }

        private void toolStripButtonSaveClick(object sender, EventArgs e)
        {
            if (_saveCompetitionDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    _competition.Save(_saveCompetitionDialog.FileName);
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log("I/O error", ex);
                    MessageBox.Show("Запись в указанный файл невозможна", "Ошибка", MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                }
            }
        }

        private void loadCompetition(string path)
        {
            resetCompetition();
            _competition.Load(path);
            foreach (var view in _raceViews)
            {
                _flowContainer.Controls.Remove(view);
            }
            _raceViews.Clear();
            foreach (var race in _competition.Races)
            {
                addRaceView(new RaceView(_competition, race));
            }
        }

        private void toolStripButtonLoadClick(object sender, EventArgs e)
        {
            if (_openCompetitionDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    loadCompetition(_openCompetitionDialog.FileName);
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log("I/O error", ex);
                    MessageBox.Show("Файл соревнования поврежден или недоступен", "Ошибка", MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                }
            }
        }

        private void resize(object sender, EventArgs e)
        {
            _expanderResults.Left = ClientSize.Width - _expanderResults.Width;
            _flowContainer.Width = _expanderResults.Left - 20;
        }

        private void toolStripButtonStartClick(object sender, EventArgs e)
        {
            var tmpFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            try
            {
                _competition.Save(tmpFile);
                CompetitionMode.Current = new ActiveCompetitionMode();
                loadCompetition(tmpFile);
                _competition.GenerateAllRaces();
            }
            catch (Exception ex)
            {
                Logger.Instance.Log("I/O error", ex);
                MessageBox.Show("Невозможно начать соревнование! Пожалуйста, перезапустите программу.",
                                "Ошибка",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
            try
            {
                File.Delete(tmpFile);
            }
            catch (Exception ex)
            {
                Logger.Instance.Log("Can't delete file", ex);
            }
        }

        private void toolStripButtonResultsClick(object sender, EventArgs e)
        {
            _expanderResults.UpdateResults(_competition);
            _expanderResults.Expand();
        }

        private void flowContainerResize(object sender, EventArgs e)
        {
            foreach (var obj in _flowContainer.Controls)
            {
                (obj as Control).Width = _flowContainer.Width - 20;
            }
        }
    }
}
